<!--
 * @Description: Stay hungry，Stay foolish
 * @Author: ''
 * @Date: 2023-10-09 22:44:20
 * @LastEditTime: 2023-10-09 23:12:35
 * @LastEditors: ''
-->
<template>
  <span>{{ result }}</span>
</template>

<script setup>
import {ref,computed,onBeforeMount,onBeforeUnmount,onMounted,watch} from "vue"

defineOptions({
  name: 'CountDown'
})

function fixedZero(val) {
  return val * 1 < 10 ? `0${val}` : val;
}

let lastTime=ref('')
let timer=ref('')
const emits=defineEmits(['on-end'])
const props=defineProps({
  // 自定义显示格式
  format: {
    type: Function
  },
  // 目标时间
  target: {
    type: [Date, Number]
  },
  // 自动倒计时间隔
  interval: {
    type: Number,
    default: 1000
  }
})

const initTime= ()=> {
  let _lastTime = 0;
  let targetTime = 0;
  try {
    if (Object.prototype.toString.call(props.target) === '[object Date]') {
      targetTime = props.target.getTime();
    } else {
      targetTime = new Date(props.target).getTime();
    }
  } catch (e) {
    throw new Error('invalid target prop', e);
  }

  _lastTime = targetTime - new Date().getTime();
  return _lastTime < 0 ? 0 : _lastTime;
}
const tick= ()=> {
  // let { lastTime } = this;

  timer.value = setTimeout(() => {
    if (lastTime.value < props.interval) {
      clearTimeout(timer.value);
      lastTime.value = 0;
      emits('on-end');  // 结束
    } else {
      lastTime.value -= props.interval;
      lastTime.value = lastTime.value;
      tick();
    }
  }, props.interval);
}
const defaultFormat= (time)=> {
  const hours = 60 * 60 * 1000;
  const minutes = 60 * 1000;

  const h = Math.floor(time / hours);
  const m = Math.floor((time - h * hours) / minutes);
  const s = Math.floor((time - h * hours - m * minutes) / 1000);

  return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`;
}

const result=computed(()=>{
  // format = defaultFormat
  const _format=props.format?props.format:defaultFormat
  return _format(lastTime.value)
})

watch(()=>props.target,()=>{
  if (timer.value) clearTimeout(timer.value);
  lastTime.value = initTime();
  tick();
})

onBeforeMount(()=>{
  lastTime.value=initTime()
})

onMounted(()=>{
  // lastTime.value=initTime()
  tick()
})

onBeforeUnmount(() => {
  if (timer.value) clearTimeout(timer.value);
})
</script>
